﻿using System;
using TestWebApplication.Models.Entities;
using System.Linq;

namespace TestWebApplication.Models.DataAccess
{
    public class DbStorage : IStorage
    {
        private readonly string connectionString;

        public DbStorage(string connectionString)
        {
            if (connectionString == null)
            {
                throw new ArgumentNullException("connectionString");
            }

            this.connectionString = connectionString;
        }

        private DataClassesDataContext CreateDbContext()
        {
            return new DataClassesDataContext(connectionString);
        }

        public void CreateUser(User user)
        {
            using(var context = CreateDbContext())
            {
                var dataUser = ConvertToDataUser(user);

                CheckExistsUserWithSameLogin(context, dataUser.login);
                
                context.data_user.InsertOnSubmit(dataUser);
                context.SubmitChanges();
            }
        }

        public string ActivateUser(string key, string shoesSize)
        {
            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException("key");
            }
            if (string.IsNullOrEmpty(shoesSize))
            {
                throw new ArgumentNullException("shoesSize");
            }

            using (var context = CreateDbContext())
            {
                var dataUser = context.data_user
                    .Where(u => (u.activation_key == key && u.is_active == false))
                    .FirstOrDefault();
                
                if (dataUser == null)
                {
                    return string.Empty;
                }

                dataUser.is_active = true;
                dataUser.shoes_size = shoesSize;
                context.SubmitChanges();

                return dataUser.login;
            }
        }

        public bool HasCreatedUser(string key)
        {
            if (string.IsNullOrEmpty(key))
            {
                return false;
            }

            using (var context = CreateDbContext())
            {
                var dataUser = context.data_user
                    .Where(u => (u.activation_key == key && u.is_active == false))
                    .FirstOrDefault();

                return dataUser != null;
            }
        }

        public bool IsUserExists(string loginName, string hash)
        {
            if(string.IsNullOrEmpty(loginName))
            {
                throw new ArgumentNullException("loginName");
            }
            if (string.IsNullOrEmpty(hash))
            {
                throw new ArgumentNullException("hash");
            }

            using (var context = CreateDbContext())
            {
                var users = context.data_user
                    .Where(u => (u.login == loginName && u.password_hash == hash && u.is_active == true))
                    .ToList();

                return users.Count > 0;
            }
        }
        
        private void CheckExistsUserWithSameLogin(DataClassesDataContext context, string login)
        {
            var users = context.data_user.Where(u => u.login == login).ToList();
            
            if (users.Count > 0)
            {
                throw new ExistsUserLoginException();
            }
        }

        private data_user ConvertToDataUser(User user)
        {
            if (user == null)
            {
                return null;
            }

            var dataUser = new data_user
                               {
                                   id = user.Id,
                                   login = user.Login,
                                   email = user.Email,
                                   password_hash = user.PasswordHash,
                                   is_active = user.IsActive,
                                   activation_key = user.ActivationKey,
                                   birthday = user.Birthday,
                                   laces_color = user.LacesColor,
                                   shoes_size = user.ShoesSize
                               };
            return dataUser;
        }

    }
}